﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Web.Configuration;
using SAMPRO.Web.GFC;
using System.Drawing;
using System.Data.SqlClient;
using System.Text;
using System.Web.Security;

public partial class install_Default : System.Web.UI.Page
{
    #region Members
    private Configuration config;
    private AppSettingsSection appSettings;
    public bool PwdValid
    {
        get
        {
            if (Session["gfcInstallModule_PwdValid"] == null)
                return false;
            return (bool)Session["gfcInstallModule_PwdValid"];
        }
        set { Session["gfcInstallModule_PwdValid"] = value; }
    }
    private bool IsPwdInstalled
    {
        get{
            return !string.IsNullOrEmpty(
                (string)appSettings.Settings["SiteInstallPassword"].Value);
        }
    }
    private bool IsInstallModuleLocked
    {
        get
        {
            if (appSettings.Settings["SiteInstallModuleLock"].Value.ToString().ToLower() == "true")
                return true;
            else
                return false;
        }
    }
    public bool IsSqlTestValid
    {
        get {
            return (bool)Session["gfcInstallModule_IsSqlTestValid"];
        }
        set { Session["gfcInstallModule_IsSqlTestValid"] = value; }
    }
    public MembershipUser NewAdmUser
    {
        get
        {
            return (MembershipUser)
                Session["gfcInstallModule_NewAdmUser"];
        }
        set
        {
            Session["gfcInstallModule_NewAdmUser"] = value;
        }
    }
    public gfcUser SelUser
    {
        get
        {
            return (gfcUser)
                Session["gfcInstallModule_SelUser"];
        }
        set
        {
            Session["gfcInstallModule_SelUser"] = value;
        }
    }
    #endregion end Members

    #region Pages

    #region Common
    protected void Page_Load(object sender, EventArgs e)
    {
        myInit();
        if (IsPwdInstalled && !IsInstallModuleLocked)
        {
            lblPwd1.Text = "Password:";
            lblPwdIsExist.Text = @"enter ""install password"" and confirmation";
            btnSavePwd.Visible = false;
        }

        if (Session["gfcInstallModule_Tab3"] != null
            && (bool)Session["gfcInstallModule_Tab3"] == true)
        {
            Session["gfcInstallModule_Tab3"] = false;
            Wizard1.ActiveStepIndex = 3;            
        }

        if (Request.Params["tab"] != null
            && Request.Params["tab"] == "3")
        {
            Session["gfcInstallModule_Tab3"] = true;
            Wizard1.ActiveStepIndex = 3;
            Response.Redirect("Default.aspx");
        }
        
        IsSqlTestValid = false;
        btnConnStrSave.Enabled = false;
        txtSqlSrvTestLog.Text = "";
        lblTestConnStrMsg.Text = "";
        txtConnStrNew.Enabled = true;
    }
    protected void myInit()
    {
        if (appSettings == null)
        {
            config =
                WebConfigurationManager.OpenWebConfiguration("~/");
            appSettings =
                config.GetSection("appSettings") as AppSettingsSection;

            Application["gfcSiteID"] =
                    (string)appSettings.Settings["gfcSiteID"].Value;
            Application["gfcSiteAuthId"] =
                "fcauth" + Application["gfcSiteID"];
            Application["gfcApiUrl"] =
                (string)appSettings.Settings["gfcApiUrl"].Value;
            Application["gfcOAuthKey"] =
                (string)appSettings.Settings["gfcOAuthKey"].Value;
            Application["gfcOAuthSecret"] =
                (string)appSettings.Settings["gfcOAuthSecret"].Value;
        }
    }
    protected string VerifyPwd()
    {
        if (txtPwd.Text != txtPwdConfirm.Text)
        {
            lblPwdIsExist.ForeColor = Color.Red;
            return "Password and confirmation do not match!";
        }
        if (appSettings.Settings["SiteInstallPassword"].Value != txtPwd.Text)
        {
            lblPwdIsExist.ForeColor = Color.Red;
            return "invalid password!";
        }
        lblPwdIsExist.ForeColor = Color.Black;
        lblPwdIsExist.Text = "set";
        PwdValid = true;
        return "";
    }
    #endregion

    #region Buttons
    protected void btnSavePwd_Click(object sender, EventArgs e)
    {
        if (txtPwd.Text != txtPwdConfirm.Text)
        {
            lblPwdIsExist.Text = "Password and confirmation do not match!";
            lblPwdIsExist.ForeColor = Color.Red;
            return;
        }
        appSettings.Settings["SiteInstallPassword"].Value = txtPwd.Text;
        lblPwdIsExist.Text = "set";
        lblPwdIsExist.ForeColor = Color.Black;
        try
        {
            config.Save();
        }
        catch (Exception err)
        {
            lblPwdIsExist.Text = err.Message;
            lblPwdIsExist.ForeColor = Color.Red;
            return;
        }
        Wizard1.ActiveStepIndex = 1;
    }
    protected void btnConnStrSave_Click(object sender, EventArgs e)
    {
        char c10 = (char)10;
        StringBuilder logStr = new StringBuilder();
        try
        {
            ConnectionStringsSection csSection =
                    config.ConnectionStrings;

            ConnectionStringSettings cs =
                    csSection.ConnectionStrings["LocalSqlServer"];
            cs.ConnectionString = txtConnStrNew.Text;
            csSection.ConnectionStrings.Remove("LocalSqlServer");
            csSection.ConnectionStrings.Add(cs);

            ConnectionStringSettings cs2 =
                    csSection.ConnectionStrings["SqlServices"];
            cs2.ConnectionString = txtConnStrNew.Text;
            csSection.ConnectionStrings.Remove("SqlServices");
            csSection.ConnectionStrings.Add(cs2);

            config.Save(ConfigurationSaveMode.Modified);

            Application["LocalSqlServer"] = txtConnStrNew.Text;

            VerifyRoles();
        }
        catch (Exception err)
        {
            logStr.Append(c10);
            logStr.Append(err.Message);
            lblTestConnStrMsg.Text = logStr.ToString();
            lblTestConnStrMsg.ForeColor = Color.Red;
        }
    }
    protected void btnSiteIdSave_Click(object sender, EventArgs e)
    {
        appSettings.Settings["gfcSiteID"].Value = txtSiteID.Text;
        appSettings.Settings["gfcOAuthKey"].Value = txtOAuthKey.Text;
        appSettings.Settings["gfcOAuthSecret"].Value = txtOAuthSecret.Text;
        try
        {
            config.Save();
            lblSiteIDMsg.Text = "Saved.";
            lblSiteIDMsg.ForeColor = Color.Green;
            Application["gfcSiteID"] =
                    (string)appSettings.Settings["gfcSiteID"].Value;
            Application["gfcSiteAuthId"] =
                "fcauth" + Application["gfcSiteID"];
            Application["gfcApiUrl"] =
                (string)appSettings.Settings["gfcApiUrl"].Value;
            Application["gfcOAuthKey"] =
                (string)appSettings.Settings["gfcOAuthKey"].Value;
            Application["gfcOAuthSecret"] =
                (string)appSettings.Settings["gfcOAuthSecret"].Value;
        }
        catch (Exception err)
        {
            lblSiteIDMsg.Text = err.Message;
        }
    }
    protected void btnSiteAdminAddToRole_Click(object sender, EventArgs e)
    {
        Exception err = null;
        bool bErr = false;
        try
        {
            if (NewAdmUser == null)
            {
                gfcUser uTmp = new gfcUser(SelUser.gfcProvider, SelUser.gfcId);
                MembershipUser uTmpNew;
                err = MembershipEx.CreateGfcUser(ref uTmp, out uTmpNew);
                if (err != null)
                {
                    bErr = true;
                    lblAdminMsg.Text = err.Message;
                }
                else
                {
                    NewAdmUser = uTmpNew;
                    Roles.AddUserToRole(SelUser.Id, "Administrators");
                }
            }
            else
            {
                Roles.AddUserToRole(SelUser.Id, "Administrators");
            }
        }
        catch (Exception ex)
        {
            lblAdminMsg.Text = ex.Message;
            lblAdminMsg.ForeColor = Color.Red;
            bErr = true;
        }
        if (bErr == false)
        {
            lblAdminMsg.Text =
@"Successfully added to Administrators group";
            lblAdminMsg.ForeColor = Color.Blue;
            btnSiteAdminAddToRole.Enabled = false;
        }
    }
    protected void cbLockInstModule_CheckedChanged(object sender, EventArgs e)
    {
        if (cbLockInstModule.Checked)
            appSettings.Settings["SiteInstallModuleLock"].Value = "true";
        else
            appSettings.Settings["SiteInstallModuleLock"].Value = "false";
        try
        {
            config.Save();
        }
        catch (Exception err)
        {
            lblLockInstModule.Text = err.Message;
            lblLockInstModule.ForeColor = Color.Red;
        }
    }
    #endregion

    #region wizard steps
    protected void Wizard1_ActiveStepChanged(object sender, EventArgs e)
    {
        #region Init
        myInit();
        if (IsInstallModuleLocked == true)
        {
            Wizard1.ActiveStepIndex = 0;
            lblPwd1.Visible = false;
            lblPwd2.Visible = false;
            txtPwd.Visible = false;
            txtPwdConfirm.Visible = false;
            btnSavePwd.Visible = false;
            lblPwdIsExist.Text =
@"Install module locked / For unlock module see file ""app.config""";
            lblPwdIsExist.ForeColor = Color.Red;
            return;
        }
        else
        {
            lblPwd1.Visible = true;
            lblPwd2.Visible = true;
            txtPwd.Visible = true;
            txtPwdConfirm.Visible = true;
            btnSavePwd.Visible = true;
        }
        if (!IsPwdInstalled)
            Wizard1.ActiveStepIndex = 0;
        if (PwdValid == false)
        {
            string pwdMsg = VerifyPwd();
            if (!String.IsNullOrEmpty(pwdMsg))
            {
                lblPwdIsExist.Text = pwdMsg;
                lblPwdIsExist.ForeColor = Color.Red;
                Wizard1.ActiveStepIndex = 0;
                if(IsPwdInstalled)
                    btnSavePwd.Visible = false;
            }
            else
                PwdValid = true;
        }
        if (Session["gfcInstallModule_Tab3"] != null
            && (bool)Session["gfcInstallModule_Tab3"] == true)
        {
            Session["gfcInstallModule_Tab3"] = false;
            Wizard1.ActiveStepIndex = 3;
        }
        else
            Session["gfcInstallModule_Tab3"] = false;
        #endregion
        #region Connection string page
        if (Wizard1.ActiveStepIndex == 1)
        {
            ConnectionStringsSection csSection =
                config.ConnectionStrings;
            ConnectionStringSettings cs =
                    csSection.ConnectionStrings["LocalSqlServer"];
            txtConnStrCur.Text = cs.ConnectionString;
            if (string.IsNullOrEmpty(txtConnStrNew.Text))
                txtConnStrNew.Text = cs.ConnectionString;
        }
        #endregion
        #region SiteID page
        if (Wizard1.ActiveStepIndex == 2)
        {
            txtSiteID.Text = appSettings.Settings["gfcSiteID"].Value;
            txtOAuthKey.Text = appSettings.Settings["gfcOAuthKey"].Value;
            txtOAuthSecret.Text = appSettings.Settings["gfcOAuthSecret"].Value;
        }
        #endregion
        #region Site Admin
        if (Wizard1.ActiveStepIndex == 3)
        {
            Session["gfcInstallModule_Tab3"] = true;
            string gfcSiteAuthId = (string)Application["gfcSiteAuthId"];
            string fcAuthToken = string.Empty;
            SelUser = null;
            NewAdmUser = null;
            if (Request.Cookies[gfcSiteAuthId] != null)
            {
                fcAuthToken = Request.Cookies[gfcSiteAuthId].Value;
                SelUser = FriendConnectUtil.getViewer(fcAuthToken);
                MembershipUser u = null;
                gfcUser gfcuser = SelUser;
                MembershipEx.GetGfcUser(ref gfcuser, out u);
                if (u == null)
                {
                    lblAdminMsg.Text =
@"To add a user to the administrators, click ""Add""";
                    lblAdminMsg.ForeColor = Color.Green;
                    btnSiteAdminAddToRole.Enabled = true;
                }
                else
                {
                    string[] s =
                        Roles.FindUsersInRole("Administrators", SelUser.Id);
                    if (s != null && s.Length > 0)
                    {
                        lblAdminMsg.Text =
@"This user is already an administrator";
                        lblAdminMsg.ForeColor = Color.Blue;
                        btnSiteAdminAddToRole.Enabled = false;
                    }
                    else
                    {
                        NewAdmUser = u;
                        lblAdminMsg.Text =
@"To add a user to the administrators, click ""Add""";
                        lblAdminMsg.ForeColor = Color.Green;
                        btnSiteAdminAddToRole.Enabled = true;
                    }
                }
            }
            else
            {
                lblAdminMsg.Text = 
@"You need to sign in to Google. Then add the user to the group Administrators.";
                lblAdminMsg.ForeColor = Color.Blue;
                btnSiteAdminAddToRole.Enabled = false;
            }
        }
        #endregion
        #region Inst module lock
        if (Wizard1.ActiveStepIndex == 4)
        {
            if (appSettings.Settings["SiteInstallModuleLock"].Value.ToString().ToLower() == "true")
                cbLockInstModule.Checked = true;
            else
                cbLockInstModule.Checked = false;
        }
        #endregion
    }
    protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
    {
        myInit();
        if (!IsPwdInstalled)
            Wizard1.ActiveStepIndex = 0;
        if (PwdValid == false)
        {
            string pwdMsg = VerifyPwd();
            if (!String.IsNullOrEmpty(pwdMsg))
            {
                lblPwdIsExist.Text = pwdMsg;
                lblPwdIsExist.ForeColor = Color.Red;
                Wizard1.ActiveStepIndex = 0;
                if (IsPwdInstalled)
                    btnSavePwd.Visible = false;
            }
            else
                PwdValid = true;
        }
    }
    protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e)
    {
        Response.Redirect(@"~\default.aspx");
    }
    #endregion

    #endregion

    #region DB

    protected void btnTestConnStr_Click(object sender, EventArgs e)
    {
        string errStr = "";
        char c10 = (char)10;
        StringBuilder logStr = new StringBuilder();
        IsSqlTestValid = false;
        SqlConnection conn = null;
        try
        {
            conn = new SqlConnection(txtConnStrNew.Text);
            conn.Open();
            logStr.Append(c10);
            logStr.Append("DB opened...");
            // tbl aspnet_Users
            if (!IsTblExist(ref conn, "aspnet_Users"))
                throw new Exception(@"Error - Table ""aspnet_Users"" not found.");
            // tbl gfc_users
            if (!IsTblExist(ref conn, "gfc_users"))
            {
                // create gfc_users
                if (!CreateTbl_gfc_users(ref conn))
                    throw new Exception(@"Error create table ""gfc_users"".");
            }
            // Verify Roles             
            if (!VerifyRoles())
                throw new Exception(@"Error verify roles in membership.");

            logStr.Append(c10);
            logStr.Append("tables structure - normal...");
            IsSqlTestValid = true;
        }
        catch (SqlException err)
        {
            errStr = err.Message;
            IsSqlTestValid = false;
        }
        catch (Exception err)
        {
            errStr = err.Message;
            IsSqlTestValid = false;
        }
        finally
        {
            if (conn != null && conn.State != System.Data.ConnectionState.Closed)
                conn.Close();
            conn = null;
        }
        if (IsSqlTestValid == false)
        {
            lblTestConnStrMsg.Text = errStr;
            lblTestConnStrMsg.ForeColor = Color.Red;
            btnConnStrSave.Enabled = false;
        }
        else
        {
            lblTestConnStrMsg.Text = "Sql connection valid.";
            txtConnStrNew.Enabled = false;
            logStr.Append(c10);
            logStr.Append(lblTestConnStrMsg.Text);
            btnConnStrSave.Enabled = true;
            lblTestConnStrMsg.ForeColor = Color.Green;
            txtSqlSrvTestLog.Text = logStr.ToString();
        }
    }
    protected bool IsTblExist(ref SqlConnection conn, string TblName)
    {
        int result = 0;
        string sql = String.Format(
@"SELECT count(*)
	FROM sys.tables
	JOIN sys.schemas
	  ON sys.tables.schema_id = sys.schemas.schema_id
   WHERE sys.schemas.name = N'dbo'
	 AND sys.tables.name = N'{0}'", TblName);

        SqlCommand cmd = new SqlCommand(sql, conn);
        result = (int)cmd.ExecuteScalar();
        if (result > 0)
            return true;
        return false;
    }
    protected bool CreateTbl_gfc_users(ref SqlConnection conn)
    {
        bool ret = true;
        int result = 0;
        string sql = String.Format(
@"
CREATE TABLE [dbo].[gfc_users](
	[Id] [uniqueidentifier] NOT NULL,
	[IdStr] [varchar](50) NOT NULL,
	[RootId] [uniqueidentifier] NULL,
	[ProviderId] [int] NOT NULL,
 CONSTRAINT [PK_gfc_users] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
");
        SqlCommand cmd = new SqlCommand(sql, conn);
        result = (int)cmd.ExecuteNonQuery();
        
        string sql2 = String.Format(
@"
CREATE UNIQUE NONCLUSTERED INDEX [IX_gfc_users_RootID] ON [dbo].[gfc_users] 
(
	[RootId] ASC,
	[ProviderId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
");
        SqlCommand cmd2 = new SqlCommand(sql2, conn);
        result = (int)cmd2.ExecuteNonQuery();

        string sql3 = String.Format(
@"
CREATE UNIQUE NONCLUSTERED INDEX [IX_gfc_users_idStr] ON [dbo].[gfc_users] 
(
	[IdStr] ASC,
	[ProviderId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
");
        SqlCommand cmd3 = new SqlCommand(sql3, conn);
        result = (int)cmd3.ExecuteNonQuery();

        string sql4 = String.Format(
@"
ALTER TABLE [dbo].[gfc_users] ADD  CONSTRAINT [DF_gfc_users_Id]  DEFAULT (newid()) FOR [Id]
");
        SqlCommand cmd4 = new SqlCommand(sql4, conn);
        result = (int)cmd4.ExecuteNonQuery();

        string sql5 = String.Format(
@"
ALTER TABLE [dbo].[gfc_users]  WITH CHECK ADD  CONSTRAINT [FK_gfc_users_gfc_users] FOREIGN KEY([RootId])
REFERENCES [dbo].[gfc_users] ([Id])
");
        SqlCommand cmd5 = new SqlCommand(sql5, conn);
        result = (int)cmd5.ExecuteNonQuery();

        string sql6 = String.Format(
@"
ALTER TABLE [dbo].[gfc_users] CHECK CONSTRAINT [FK_gfc_users_gfc_users]
");
        SqlCommand cmd6 = new SqlCommand(sql6, conn);
        result = (int)cmd6.ExecuteNonQuery();

        return ret;
    }
    protected bool VerifyRoles()
    {
        bool ret = true;
        if(!Roles.RoleExists("Administrators"))
            Roles.CreateRole("Administrators");
        if (!Roles.RoleExists("Users"))
            Roles.CreateRole("Users");
        if (!Roles.RoleExists("Guests"))
            Roles.CreateRole("Guests");
        return ret;
    }

    #endregion

}